/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief MaCI - Energy Server interface header.
 * \author Antti Maula <antti.maula@tkk.fi>
 * \author Marek Matusiak
 *
 * $Id: EnergyServer.hpp,v 1.4 2009-09-23 11:56:14 morsko Exp $
 *
 */
#ifndef _MACI_INTERFACE_ENERGYSERVER_HPP_
#define _MACI_INTERFACE_ENERGYSERVER_HPP_
#include "MaCI.hpp"
#include "EnergyData.hpp"
#include "sync.hpp"
#include "thread.hpp"
#include <list>


// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
  class GIMIMessage;
}

namespace MaCI {
  namespace Energy {

    /** MaCI - Energy Server interface
     * 
     * This class contains the methods and types for providing
     * the Energy service in the GIMnet.
     */
    class CEnergyServer : public MaCI::CMaCI
       //#ifdef _MACI_INTERFACE_SERVER_USE_THREAD_RECEIVER_
                      //,private gim::CSync,
                      // private gim::CThread
       //#endif //_MACI_INTERFACE_SERVER_USE_THREAD_RECEIVER_
    {
    public:
      /** Constructor.
       * 
       * Constructor of the EnergyServer. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aMaCICtrlServerPtr Pointer to GIMI used for communication
       * @param[in] aInterfaceMinor Interface minor number. Usually
       * used to indicate the instance of devices of same type.
       * @param[in] aDescription User provided description about
       * service. This description will be appended after text
       * 'MaCI-EnergyServer; ' in the GIMI service description
       * field.
       * @param[in] aInstanceName Specify Instance name here.
       */
      CEnergyServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, 
                   const int aInterfaceMinor,
                   const std::string &aDescription = "",
                   const std::string &aInstanceName = "");


      /** Destructor.
       */
      ~CEnergyServer();
 

      /** Send EnergyData element
       *
       * This function sends an EnergyData container to service
       * subscribers.\n
       *
       * The container to send must contain atleast the following
       * elements:\n
       * \li \c TTimestamp
       * \li \c TEnergyEvent
       *
       * @param[in] aEnergyData   CEnergyData container containing data to send.
       * @return                 Returns a value of type MaCI::EMaCIError.
       */
      MaCI::EMaCIError SendEnergyEvent(const CEnergyData &aEnergyData);

      
      /** Return next incoming command in Queue.
       *
       * This function waits for new commands to arrive for a maximum
       * of 'aTimeout_ms' milliseconds. If a command is received, it
       * is stored to reference 'aData', and the function will return
       * KMaCIOK.
       *
       * @param[out] aData      Reference to CEnergyData to be filled with
       *                        received information.
       * @param[out] aSource    Reference to message source information. This
       *                        is required for example for REPLY operations.
       * @param[in] aTimeout_ms Timeout in milliseconds to sleep waiting
       *                        for the operation to complete. If this
       *                        timeout exceeds and no commands are
       *                        received, this function returns KMaCITimeout.
       *
       * @return                \c 'KMaCIOK' on succesfully received command.\n
       *                        \c 'KMaCITimeout' if timeout value exceeded.\n
       *                        \c 'KMaCIInvalidFormat' if the client received
       *                        a message of invalid format. It is safe to ignore this,
       *                        as it is only a notification for the application
       *                        that an invalid message was received. The event
       *                        is returned as it may help tracing down some
       *                        implementation problems.
       */
      MaCI::EMaCIError WaitCommand(CEnergyData &aData,
                                   SMessageSource &aSource,
                                   const unsigned int aTimeout_ms);

      /** Send reply to client.
       * 
       * This function sends synchronous reply message to client.
       *
       * @param[in] aData       Reference to CParameterData. This data will be sent to
       *                        client for reply
       * @param[in] aInfo       Reference to replyInfo. Get this replyinfo from
       *                        WaitCommand.
       * @return                'KMaCIOK' when reply message succesfully sent.
       *                        Other errors returned when appropriate.
       *                        (See the MaCI::EMaCIError for description)
       * \see EMaCIError
       */
      MaCI::EMaCIError SendReply(const CEnergyData &aData, 
                                 const SMessageSource &aSource);
      
    protected:
      /** Open device.
       *
       * Opens the device, basicly registers device to GIMI.
       *  
       * @return                Returns a value of type MaCI::EMaCIError. 
       *                        
       * \see EMaCIError
       */
      MaCI::EMaCIError DoOpen(void);
      
      
      /** Close device.
       *
       * Closes the device. Closes all GIMI registrations and queues.
       *
       * @return                Returns a value of type EMaCIError.
       *
       * \see EMaCIError
       */
      MaCI::EMaCIError DoClose(void);

    private:
      //#ifdef _MACI_INTERFACE_SERVER_USE_THREAD_RECEIVER_
      //int ProcessMessage(const CEnergyData &aMessage, const SMessageSource &aSource); ///< Process message func.
      //int ThreadFunction(const int aThreadNumber); ///< Incoming data handler function
      //std::list<CEnergyData> iCommandQueue; ///< Queue for received commands NOT handled by thread.
      //#endif // _MACI_INTERFACE_SERVER_USE_THREAD_RECEIVER_

      bool iServerActive; ///< Is the server active? - flag
      std::string iServiceDescription; ///< User provided service description field.
      unsigned int iEnergySequenceNumber;
    };

  }
}


#endif //_MACI_INTERFACE_ENERGYSERVER_HPP_
